<template>
  <div class="app-container">
    <el-card>
      <template #header>
        <div class="card-header">
          <span style="font-weight: 600;">
            <el-icon style="margin-right: 8px;"><Document /></el-icon>
            系统日志
          </span>
        </div>
      </template>

      <!-- Tab切换 -->
      <el-tabs v-model="activeTab" @tab-change="handleTabChange">
        <el-tab-pane label="控制端日志" name="server">
          <div class="log-section">
            <div class="log-toolbar">
              <el-input
                v-model="serverLogFilter"
                placeholder="过滤日志（支持客户端ID）"
                style="width: 300px; margin-right: 10px;"
                clearable
              />
              <el-input-number
                v-model="serverLogLines"
                :min="100"
                :max="10000"
                :step="100"
                style="width: 150px; margin-right: 10px;"
              />
              <el-button icon="Refresh" @click="loadServerLogs">刷新</el-button>
              <el-switch
                v-model="serverAutoRefresh"
                active-text="自动刷新"
                inactive-text="手动刷新"
                style="margin-left: 12px;"
              />
              <el-button icon="Download" @click="downloadServerLogs" style="margin-left: 12px;">下载</el-button>
            </div>
            <div
              ref="serverLogContentRef"
              class="log-content"
              v-loading="serverLogLoading"
            >
              <pre v-if="serverLogText" class="log-text">{{ serverLogText }}</pre>
              <div v-else class="log-empty">暂无日志</div>
            </div>
          </div>
        </el-tab-pane>

        <el-tab-pane label="实时日志" name="realtime">
          <div class="log-section">
            <div class="log-toolbar">
              <el-input
                v-model="realtimeLogFilter"
                placeholder="过滤日志（支持客户端ID、账号、事件类型）"
                style="width: 300px; margin-right: 10px;"
                clearable
              />
              <el-button icon="Delete" @click="clearRealtimeLogs">清空</el-button>
              <el-switch
                v-model="realtimeAutoRefresh"
                active-text="自动接收"
                inactive-text="暂停接收"
                style="margin-left: 12px;"
              />
              <el-button icon="Download" @click="downloadRealtimeLogs" style="margin-left: 12px;">下载</el-button>
            </div>
            <div
              ref="realtimeLogContentRef"
              class="log-content"
            >
              <div v-if="realtimeLogs.length === 0" class="log-empty">暂无实时日志</div>
              <div v-else class="realtime-log-list">
                <div
                  v-for="(log, index) in filteredRealtimeLogs"
                  :key="index"
                  class="realtime-log-item"
                  :class="getLogItemClass(log)"
                >
                  <div class="log-time">{{ formatLogTime(log.timestamp) }}</div>
                  <div class="log-client">{{ log.client_id || '未知客户端' }}</div>
                  <div class="log-account">{{ log.account || '-' }}</div>
                  <div class="log-type">{{ log.type || 'info' }}</div>
                  <div class="log-message">{{ log.message }}</div>
                </div>
              </div>
            </div>
          </div>
        </el-tab-pane>
      </el-tabs>
    </el-card>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, nextTick, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { Document } from '@element-plus/icons-vue'
import { useRoute } from 'vue-router'
import { getAgentLogs } from '@/api/agent'
import { websocketManager } from '@/utils/websocket'

// ==================== Tab切换 ====================
const route = useRoute()
const activeTab = ref('server')

// 如果是通过搜索页的"实时日志"按钮打开，自动切换到实时日志tab
onMounted(() => {
  if (route.query.tab === 'realtime') {
    activeTab.value = 'realtime'
  }
})

function handleTabChange(tabName) {
  if (tabName === 'server') {
    loadServerLogs()
  } else if (tabName === 'realtime') {
    // 实时日志tab切换时，确保WebSocket连接
    ensureWebSocketConnection()
  }
}

// ==================== 控制端日志 ====================
const serverLogText = ref('')
const serverLogLoading = ref(false)
const serverLogFilter = ref('')
const serverLogLines = ref(500)
const serverAutoRefresh = ref(false)
const serverLogContentRef = ref(null)
let serverLogAutoRefreshTimer = null

async function loadServerLogs() {
  serverLogLoading.value = true
  try {
    const clientIdFilter = (serverLogFilter.value && serverLogFilter.value.trim()) || null
    const res = await getAgentLogs(clientIdFilter, serverLogLines.value)
    if (res.code === 200 && res.data) {
      const logs = res.data.logs || []
      serverLogText.value = logs.join('')
      // 自动滚动到底部
      nextTick(() => {
        if (serverLogContentRef.value) {
          serverLogContentRef.value.scrollTop = serverLogContentRef.value.scrollHeight
        }
      })
    } else {
      ElMessage.error(res.msg || '获取日志失败')
      serverLogText.value = ''
    }
  } catch (error) {
    console.error('加载日志失败:', error)
    ElMessage.error('加载日志失败：' + (error.message || '未知错误'))
    serverLogText.value = ''
  } finally {
    serverLogLoading.value = false
  }
}

watch(serverAutoRefresh, (val) => {
  if (val) {
    serverLogAutoRefreshTimer = setInterval(() => {
      loadServerLogs()
    }, 3000)
    ElMessage.success('已开启自动刷新')
  } else {
    if (serverLogAutoRefreshTimer) {
      clearInterval(serverLogAutoRefreshTimer)
      serverLogAutoRefreshTimer = null
    }
    ElMessage.info('已停止自动刷新')
  }
})

function downloadServerLogs() {
  if (!serverLogText.value) {
    ElMessage.warning('没有日志可下载')
    return
  }
  const blob = new Blob([serverLogText.value], { type: 'text/plain;charset=utf-8' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = `server-logs-${new Date().toISOString().slice(0, 10)}.txt`
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
  URL.revokeObjectURL(url)
  ElMessage.success('日志下载成功')
}

// ==================== 实时日志 ====================
const REALTIME_LOGS_STORAGE_KEY = 'agent_realtime_logs'
const realtimeLogs = ref([])
const realtimeLogFilter = ref('')
const realtimeAutoRefresh = ref(true)
const realtimeLogContentRef = ref(null)

// ✅ 从localStorage加载保存的实时日志（任务重新运行前保留）
function loadRealtimeLogsFromStorage() {
  try {
    const stored = localStorage.getItem(REALTIME_LOGS_STORAGE_KEY)
    if (stored) {
      const logs = JSON.parse(stored)
      // 只保留最近24小时内的日志
      const oneDayAgo = Date.now() - 24 * 60 * 60 * 1000
      const filteredLogs = logs.filter(log => {
        const logTime = new Date(log.timestamp).getTime()
        return logTime > oneDayAgo
      })
      realtimeLogs.value = filteredLogs
      console.log(`[LogView] 从localStorage加载了 ${filteredLogs.length} 条实时日志`)
    }
  } catch (error) {
    console.error('加载实时日志失败:', error)
  }
}

// ✅ 保存实时日志到localStorage
function saveRealtimeLogsToStorage() {
  try {
    localStorage.setItem(REALTIME_LOGS_STORAGE_KEY, JSON.stringify(realtimeLogs.value))
  } catch (error) {
    console.error('保存实时日志失败:', error)
  }
}

// 过滤后的实时日志
const filteredRealtimeLogs = computed(() => {
  if (!realtimeLogFilter.value) {
    return realtimeLogs.value
  }
  const filter = realtimeLogFilter.value.toLowerCase()
  return realtimeLogs.value.filter(log => {
    const clientId = (log.client_id || '').toLowerCase()
    const account = (log.account || '').toLowerCase()
    const type = (log.type || '').toLowerCase()
    const message = (log.message || '').toLowerCase()
    return clientId.includes(filter) ||
           account.includes(filter) ||
           type.includes(filter) ||
           message.includes(filter)
  })
})

// 确保WebSocket连接
function ensureWebSocketConnection() {
  if (!websocketManager.isConnected()) {
    websocketManager.connect()
  }
}

// 处理WebSocket消息
function handleWebSocketMessage(data) {
  if (!realtimeAutoRefresh.value) return
  
  const payload = data.payload || data
  
  // 处理不同类型的实时日志
  const logEntry = {
    timestamp: new Date().toISOString(),
    client_id: '',
    account: '',
    type: 'info',
    message: ''
  }
  
  // 账号封禁
  if (payload.type === 'client_status' && payload.data?.banned) {
    logEntry.client_id = payload.data.client_id || ''
    logEntry.account = payload.data.account || payload.data.account_nickname || ''
    logEntry.type = 'warning'
    logEntry.message = `账号被封禁: ${payload.data.account || payload.data.client_id}`
    addRealtimeLog(logEntry)
  }
  
  // 下单成功/失败
  if (payload.type === 'client_response' && payload.event === 'order') {
    const messageData = payload.message?.data || {}
    logEntry.client_id = payload.client_id || messageData.client_id || ''
    logEntry.account = messageData.account || ''
    logEntry.type = payload.message?.success ? 'success' : 'error'
    logEntry.message = payload.message?.success
      ? `下单成功: 商品 ${messageData.item_id || ''}，价格 ¥${messageData.price || ''}`
      : `下单失败: ${payload.message?.msg || payload.message?.error || '未知错误'}`
    addRealtimeLog(logEntry)
  }
  
  // 订单错误（业务错误或系统错误）
  if (payload.type === 'client_response' && payload.event === 'order_error') {
    const errorData = payload.message?.data || {}
    logEntry.client_id = payload.client_id || ''
    logEntry.account = errorData.account || ''
    const isBusinessError = errorData.is_business_error
    const isBanned = errorData.is_banned
    
    if (isBanned) {
      logEntry.type = 'error'
      logEntry.message = `❌ 订单失败（账号封禁）: ${payload.message?.msg || '账号已被封禁'}`
    } else if (isBusinessError) {
      logEntry.type = 'warning'
      logEntry.message = `⚠️  订单警告（业务错误）: ${payload.message?.msg || '库存锁定或PC不支持等'}`
    } else {
      logEntry.type = 'error'
      logEntry.message = `❌ 订单失败: ${payload.message?.msg || '未知错误'}`
    }
    addRealtimeLog(logEntry)
  }
  
  // API错误
  if (payload.type === 'client_response' && payload.event === 'api_error') {
    const errorData = payload.message?.data || {}
    logEntry.client_id = payload.client_id || ''
    logEntry.type = 'error'
    logEntry.message = `❌ API错误: ${payload.message?.msg || 'API请求异常'} (${errorData.error_code || ''})`
    addRealtimeLog(logEntry)
  }
  
  // 主机断开
  if (payload.type === 'client_disconnected') {
    logEntry.client_id = payload.client_id || ''
    logEntry.type = 'error'
    logEntry.message = `主机断开: ${payload.client_id || '未知主机'}`
    addRealtimeLog(logEntry)
  }
  
  // 账号登录/登录失败
  if (payload.type === 'client_status') {
    const loginStatus = payload.data?.login_status
    if (loginStatus === 'logged_in') {
      logEntry.client_id = payload.data.client_id || ''
      logEntry.account = payload.data.account || payload.data.account_nickname || ''
      logEntry.type = 'success'
      logEntry.message = `账号登录成功: ${payload.data.account || payload.data.client_id}`
      addRealtimeLog(logEntry)
    } else if (loginStatus === 'login_error' || loginStatus === 'account_banned') {
      logEntry.client_id = payload.data.client_id || ''
      logEntry.account = payload.data.account || payload.data.account_nickname || ''
      logEntry.type = 'error'
      logEntry.message = `账号登录失败: ${payload.data.account || payload.data.client_id} - ${payload.data.last_error || '账号被封禁或登录异常'}`
      addRealtimeLog(logEntry)
    }
    
    // 账号下线（工作状态变为空闲或离线）
    if (payload.data?.work_status === 'idle' && loginStatus !== 'logged_in') {
      logEntry.client_id = payload.data.client_id || ''
      logEntry.account = payload.data.account || payload.data.account_nickname || ''
      logEntry.type = 'warning'
      logEntry.message = `账号下线: ${payload.data.account || payload.data.client_id}`
      addRealtimeLog(logEntry)
    }
    
    // 浏览器状态变化
    if (payload.data?.browser_status) {
      const browserStatus = payload.data.browser_status
      if (browserStatus === 'stopped' || browserStatus === 'error') {
        logEntry.client_id = payload.data.client_id || ''
        logEntry.account = payload.data.account || payload.data.account_nickname || ''
        logEntry.type = browserStatus === 'error' ? 'error' : 'warning'
        logEntry.message = `浏览器${browserStatus === 'error' ? '异常' : '已停止'}: ${payload.data.client_id || '未知主机'}`
        addRealtimeLog(logEntry)
      }
    }
  }
  
  // ✅ 搜索日志（主要操作）
  if (payload.type === 'client_response') {
    const event = payload.event || payload.message?.event
    if (event === 'search') {
      const messageData = payload.message?.data || {}
      // ✅ 改进：从多个位置尝试获取keyword（message.data.keyword, message.data.data.keyword等）
      const keyword = messageData.keyword || 
                      (messageData.data && messageData.data.keyword) || 
                      (payload.message && payload.message.data && payload.message.data.keyword) ||
                      (payload.data && payload.data.keyword) ||
                      '未知关键词'
      const items = messageData.results || messageData.items || []
      const total = messageData.total || items.length
      const filtered = messageData.filtered || total
      const newCount = messageData.new_count || (messageData.new_items?.length || 0)
      
      logEntry.client_id = payload.client_id || ''
      // 尝试从状态更新中获取账号信息
      logEntry.account = payload.account || messageData.account || ''
      
      if (payload.message?.success) {
        logEntry.type = 'info'
        // ✅ 搜索简要日志：时间、主机、账号、搜索结果
        logEntry.message = `搜索完成 | 关键词: ${keyword} | 总数: ${total} | 过滤后: ${filtered} | 新商品: ${newCount}`
      } else {
        logEntry.type = 'error'
        logEntry.message = `搜索失败 | 关键词: ${keyword} | 错误: ${payload.message?.msg || payload.message?.error || '未知错误'}`
      }
      addRealtimeLog(logEntry)
    }
    
    // ✅ API请求异常（FAIL_SYS_ILLEGAL_ACCESS：签名不对、参数有误等）
    if (event === 'api_error' || payload.event === 'api_error') {
      const errorData = payload.data || payload.message?.data || {}
      logEntry.client_id = payload.client_id || errorData.client_id || ''
      // ✅ 优先从消息顶层获取账号信息，其次从data中获取
      logEntry.account = payload.account || errorData.account || ''
      logEntry.type = 'error'
      
      // ✅ 改进：显示详细的请求诊断信息
      const apiName = errorData.api || '未知'
      const errorCode = errorData.error_code || 'N/A'
      const errorMsg = errorData.error_msg || '未知错误'
      
      let message = `⚠️ API请求异常 | API: ${apiName} | 错误码: ${errorCode} | 错误: ${errorMsg}`
      
      // 如果有详细的请求信息，添加到日志消息中（用于诊断）
      if (errorData.request_details) {
        const details = errorData.request_details
        message += `\n📋 请求详情:\n`
        message += `  - URL: ${details.url || 'N/A'}\n`
        message += `  - Method: ${details.method || 'POST'}\n`
        message += `  - Headers: ${JSON.stringify(details.headers || {}, null, 2)}\n`
        message += `  - Cookies: ${JSON.stringify(details.cookies || {}, null, 2)}\n`
        message += `  - POST Data: ${details.post_data || details.post_data_encoded || 'N/A'}\n`
        message += `  - Timestamp: ${details.timestamp || 'N/A'}\n`
        message += `  - Sign: ${details.sign || 'N/A'}\n`
        message += `  - App Key: ${details.app_key || 'N/A'}`
      } else if (errorData.request_data) {
        // 兼容旧格式：只有request_data
        message += ` | 请求数据: ${JSON.stringify(errorData.request_data)}`
      }
      
      logEntry.message = message
      addRealtimeLog(logEntry)
    }
  }
  
  // ✅ 处理从TCP直接发送的错误消息（格式：event=api_error）
  if (payload.event === 'api_error' && payload.direction === 'res') {
    const errorData = payload.data || {}
    logEntry.client_id = payload.client_id || ''
    logEntry.account = payload.account || ''
    logEntry.type = 'error'
    const apiName = errorData.api || '未知API'
    const errorMsg = errorData.error_msg || payload.msg || '未知错误'
    logEntry.message = `⚠️ 主机异常 | API: ${apiName} | 错误: ${errorMsg}`
    addRealtimeLog(logEntry)
  }
}

function addRealtimeLog(logEntry) {
  // ✅ 确保时间戳精确到毫秒
  if (!logEntry.timestamp) {
    logEntry.timestamp = new Date().toISOString()
  }
  
  realtimeLogs.value.push(logEntry)
  // 限制日志数量，最多保留2000条（增加容量）
  if (realtimeLogs.value.length > 2000) {
    realtimeLogs.value.shift()
  }
  
  // ✅ 保存到localStorage（任务重新运行前保留）
  saveRealtimeLogsToStorage()
  
  // 自动滚动到底部
  nextTick(() => {
    if (realtimeLogContentRef.value) {
      realtimeLogContentRef.value.scrollTop = realtimeLogContentRef.value.scrollHeight
    }
  })
}

function clearRealtimeLogs() {
  realtimeLogs.value = []
  // ✅ 同时清除localStorage中的日志
  localStorage.removeItem(REALTIME_LOGS_STORAGE_KEY)
  ElMessage.success('已清空实时日志')
}

function downloadRealtimeLogs() {
  if (realtimeLogs.value.length === 0) {
    ElMessage.warning('没有日志可下载')
    return
  }
  const logText = realtimeLogs.value.map(log => {
    return `[${formatLogTime(log.timestamp)}] [${log.type.toUpperCase()}] [${log.client_id}] ${log.message}`
  }).join('\n')
  const blob = new Blob([logText], { type: 'text/plain;charset=utf-8' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = `realtime-logs-${new Date().toISOString().slice(0, 10)}.txt`
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
  URL.revokeObjectURL(url)
  ElMessage.success('日志下载成功')
}

function formatLogTime(timestamp) {
  if (!timestamp) return '-'
  const date = new Date(timestamp)
  // ✅ 精确到毫秒：YYYY-MM-DD HH:mm:ss.SSS
  const year = date.getFullYear()
  const month = String(date.getMonth() + 1).padStart(2, '0')
  const day = String(date.getDate()).padStart(2, '0')
  const hours = String(date.getHours()).padStart(2, '0')
  const minutes = String(date.getMinutes()).padStart(2, '0')
  const seconds = String(date.getSeconds()).padStart(2, '0')
  const milliseconds = String(date.getMilliseconds()).padStart(3, '0')
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${milliseconds}`
}

function getLogItemClass(log) {
  return {
    'log-item-info': log.type === 'info',
    'log-item-success': log.type === 'success',
    'log-item-warning': log.type === 'warning',
    'log-item-error': log.type === 'error'
  }
}

// WebSocket消息处理器
const wsHandler = (data) => {
  handleWebSocketMessage(data)
}

// 生命周期
onMounted(() => {
  // ✅ 从localStorage加载保存的实时日志（任务重新运行前保留）
  loadRealtimeLogsFromStorage()
  
  // 初始化加载控制端日志
  if (activeTab.value === 'server') {
    loadServerLogs()
  }
  
  // 监听WebSocket消息（websocketManager.on 接受的是处理器函数）
  ensureWebSocketConnection()
  websocketManager.on(wsHandler)
})

onUnmounted(() => {
  // 清理定时器
  if (serverLogAutoRefreshTimer) {
    clearInterval(serverLogAutoRefreshTimer)
  }
  
  // 移除WebSocket监听
  websocketManager.off(wsHandler)
})
</script>

<script>
export default {
  name: 'LogView'
}
</script>

<style scoped>
.app-container {
  padding: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.log-section {
  height: 600px;
  display: flex;
  flex-direction: column;
}

.log-toolbar {
  display: flex;
  align-items: center;
  margin-bottom: 12px;
  padding-bottom: 12px;
  border-bottom: 1px solid #e4e7ed;
}

.log-content {
  flex: 1;
  overflow: auto;
  background: #1e1e1e;
  border-radius: 4px;
  padding: 12px;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
}

.log-text {
  margin: 0;
  color: #d4d4d4;
  font-size: 12px;
  line-height: 1.6;
  white-space: pre-wrap;
  word-wrap: break-word;
}

.log-empty {
  color: #909399;
  text-align: center;
  padding: 40px;
}

/* 实时日志列表样式 */
.realtime-log-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.realtime-log-item {
  display: grid;
  grid-template-columns: 200px 120px 120px 80px 1fr;
  gap: 12px;
  padding: 8px 12px;
  border-radius: 4px;
  background: #252526;
  font-size: 12px;
  line-height: 1.5;
  align-items: center;
}

.realtime-log-item.log-item-info {
  border-left: 3px solid #409EFF;
}

.realtime-log-item.log-item-success {
  border-left: 3px solid #67C23A;
}

.realtime-log-item.log-item-warning {
  border-left: 3px solid #E6A23C;
}

.realtime-log-item.log-item-error {
  border-left: 3px solid #F56C6C;
}

.log-time {
  color: #858585;
}

.log-client {
  color: #569CD6;
}

.log-account {
  color: #9CDCFE;
  font-weight: 500;
}

.log-type {
  color: #C586C0;
  text-transform: uppercase;
  font-weight: 600;
}

.log-message {
  color: #D4D4D4;
}

.log-item-info .log-type {
  color: #569CD6;
}

.log-item-success .log-type {
  color: #6A9955;
}

.log-item-warning .log-type {
  color: #DCDCAA;
}

.log-item-error .log-type {
  color: #F48771;
}
</style>

